package controller

import (
	"ahutoj/web/io/constanct"
	"ahutoj/web/io/request"
	"ahutoj/web/io/response"
	"ahutoj/web/logic"
	"ahutoj/web/middlewares"
	"ahutoj/web/utils"
	"strconv"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
)

// @Summary	添加题单
// @Description
// @Tags		Training
// @Accept		json
// @Produce	json
// @Param		ListAll	body		request.ListAll	true	"-"
// @Success	200		{object}	response.AddTrainResp
// @Router		/api/training/add/ [post]
func AddTraining(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.ListAll)
	err := ctx.ShouldBindWith(req, binding.JSON)
	if err != nil {
		// 请求参数有误 直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	// fmt.Printf("req:%+v\n", req)

	resp, err := logic.AddTraining(req, ctx)
	if err != nil {
		logger.Errorf("call AddTraining failed,req=%+v,err=%s", *req, err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	加入题单
// @Description
// @Tags		Training
// @Accept		json
// @Produce	json
// @Param		RegisterTrainingReq	body		request.RegisterTrainingReq	true	"-"
// @Success	200					{object}	response.Response
// @Router		/api/training/user/ [post]
func RegisterTraining(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.RegisterTrainingReq)
	err := ctx.ShouldBindWith(req, binding.JSON)
	if err != nil {
		// 请求参数有误 直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	req.UID = middlewares.GetUid(ctx)
	if req.UID == "" {
		response.ResponseError(ctx, constanct.AUTH_Token_EmptyCode)
	}
	// fmt.Printf("req:%+v\n", req)

	resp, err := logic.RegisterTraining(ctx, req)
	if err != nil {
		logger.Errorf("call RegisterTraining failed,req=%+v,err=%s", *req, err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	编辑题单
// @Description
// @Tags		Training
// @Accept		json
// @Produce	json
// @Param		EditListReq	body		request.EditListReq	true	"-"
// @Success	200			{object}	response.Response
// @Router		/api/training/edit/ [post]
func EditTraining(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.EditListReq)
	err := ctx.ShouldBindWith(req, binding.JSON)
	if err != nil {
		// 请求参数有误 直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	// fmt.Printf("req:%+v\n", req)

	resp, err := logic.EditTraining(req, ctx)
	if err != nil {
		logger.Errorf("call EditTraining failed,req=%+v,err=%s", *req, err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	删除题单
// @Description
// @Tags		Training
// @Accept		json
// @Produce	json
// @Param		DelListReq	body		request.DelListReq	true	"-"
// @Success	200			{object}	response.Response
// @Router		/api/training/delete/ [post]
func DeleteTraining(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.DelListReq)
	err := ctx.ShouldBindWith(req, binding.JSON)
	if err != nil {
		// 请求参数有误 直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	// fmt.Printf("req:%+v\n", req)

	resp, err := logic.DeleteTraining(req, ctx)
	if err != nil {
		logger.Errorf("call DeleteTraining failed,req=%+v,err=%s", *req, err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	获取题单列表
// @Description
// @Tags		Training
// @Accept		json
// @Produce	json
// @Param		TrainingListReq	body		request.TrainingListReq	true	"-"
// @Success	200				{object}	response.TrainingListResp
// @Router		/api/training/list [get]
func GetListTraining(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.TrainingListReq)
	if err := ctx.ShouldBindWith(req, binding.Query); err != nil {
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	resp, err := logic.GetTrainingList(ctx, req)
	if err != nil {
		logger.Errorf("call GetTrainingList failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	获取题单详情
// @Description
// @Tags		Training
// @Accept		json
// @Produce	json
// @Param		id	path		int	true	"-"
// @Success	200	{object}	response.GetTrainResp
// @Router		/api/training/{id} [get]
func GetTraining(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	var err error
	req := new(request.TrainingReq)
	LIDStr := ctx.Param("id")
	req.LID, err = strconv.ParseInt(LIDStr, 10, 64)
	if err != nil {
		logger.Errorf("call GetContest fialed,err=%s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	// logger.Infof("req:%+v", utils.Sdump(req))
	resp, err := logic.GetTraining(ctx, req)
	if err != nil {
		logger.Errorf("call GetTraining failed,err = %s", err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	获取题单排名
// @Description
// @Tags		Training
// @Accept		json
// @Produce	json
// @Param		GetListReq	query		request.GetListReq	true	"-"
// @Param		id			path		int					true	"-"
// @Success	200			{object}	response.TrainingRankResp
// @Router		/api/training/{id}/rank [get]
func GetRankTraining(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.GetTrainingRankReq)
	LIDStr := ctx.Param("id")
	if LIDStr == "" {
		logger.Errorf("lid is empty")
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	var err error
	if err = ctx.ShouldBindWith(&req, binding.Query); err != nil {
		logger.Errorf("call Param failed, err")
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	req.LID, err = strconv.ParseInt(LIDStr, 10, 64)
	if err != nil {
		logger.Errorf("call GetTraining fialed,err=%s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	resp, err := logic.GetRankTraining(ctx, req)
	if err != nil {
		logger.Errorf("call GetRankTraining failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	获取题单用户信息
// @Description
// @Tags		Training
// @Accept		json
// @Produce	json
// @Param		ListUserReq	query		request.ListUserReq	true	"-"
// @Success	200			{object}	response.TrainingUserResp
// @Router		/api/training/user [get]
func GetTrainUserInfo(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.ListUserReq)
	err := ctx.ShouldBindWith(req, binding.Query)
	if err != nil {
		// 请求参数有误 直接返回响应
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	// fmt.Printf("req:%+v\n", req)
	// logger.Debugf("req:%+v", utils.Sdump(req))
	resp, err := logic.GetTrainUserInfo(ctx, req)
	if err != nil {
		logger.Errorf("call GetTrainUserInfo failed,req=%+v,err=%s", *req, err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}

// @Summary	克隆题单
// @Description
// @Tags		Training
// @Accept		json
// @Produce	json
// @Param		CloneTraniningReq	body		request.CloneTraniningReq	true	"-"
// @Success	200					{object}	response.CloneTraniningResp
// @Router		/api/training/clone/ [post]
func CloneTranining(ctx *gin.Context) {
	logger := utils.GetLogInstance()
	req := new(request.CloneTraniningReq)
	err := ctx.ShouldBindWith(req, binding.JSON)
	if err != nil {
		// 请求参数有误 直接返回响应CloneTrainUser
		logger.Errorf("call ShouldBindWith failed, err = %s", err.Error())
		response.ResponseError(ctx, constanct.InvalidParamCode)
		return
	}
	// fmt.Printf("req:%+v\n", req)

	resp, err := logic.CloneTrainUser(ctx, req)
	if err != nil {
		logger.Errorf("call CloneTrainUser failed,req=%+v,err=%s", *req, err.Error())
		response.ResponseError(ctx, constanct.ServerErrorCode)
		return
	}
	response.ResponseOK(ctx, resp)
}
